<?php
/**
 * Classe para gerenciar o Fluxo de Carência
 * @author bruno
 * @since 27/04/2010
 */
class FluxoCarencia implements InterfaceFluxo
{
    const ERRO_AUTORIZACAO = 'Você não tem autorização suficiente para realizar esta operação neste momento.';
    
    public static function solicitar($lotacaoid, $cargoid, $quantidade, $parecer)
    {
        self::isAuthorized('solicitar', NULL, TRUE);
        
        global $usuario, $pfcid;
    	
        switch ($pfcid) {
            case PerfilComportamental::Gabinete:
                $statusid = Status::Carencia_Solicitada_NucleoCentral;
                break;
            case PerfilComportamental::Orgao:
                $statusid = Status::Carencia_Solicitada_Orgao;
                break;
            case PerfilComportamental::NucleoGestor:
                $statusid = Status::Carencia_Solicitada_NucleoGestor;
                break;
            default:
                throw new Exception('Solicitante Inválido.');
                break;
        }
        
    	try {         
			pg_query(conexao::Conectar(), "begin");
			
	        for ($i=0; $i < $quantidade; $i++) {
        		$carencia = new Carencia();
        		$carencia->lotacaoid = $lotacaoid;
            	$carencia->cargoid = $cargoid;
            	$carencia->data = date("d/m/Y H:m:i");
            	$carencia->ativa = TRUE;
            	$carencia->operadorid = $usuario->operadorid;         	
            	$carencia->salvar();
            	
            	$carencia->inserirHistorico($statusid, $parecer);        		
        	}				
            pg_query(conexao::Conectar(), "commit");
        }
		catch (Exception $e){
            pg_query(conexao::Conectar(), "rollback");
            throw new Exception($e->getMessage());
		}        
    }
    
    public static function aprovar(Carencia $carencia, $parecer, $vagaid = NULL)
    {
        self::isAuthorized('aprovar', $carencia, TRUE);
        
        if (empty($parecer)){
    	    throw new Exception('Parecer é obrigatório.');
    	}
    	
    	global $usuario, $pfcid;
    	
        switch ($pfcid) {
            case PerfilComportamental::Gabinete:
                $statusid = Status::Carencia_Aprovada_NucleoCentral;
                break;
            case PerfilComportamental::Orgao:
                $statusid = Status::Carencia_Aprovada_Orgao;
                break;
            default:
                throw new Exception('Solicitante Inválido.');
                break;
        }
    	
    	try {
			pg_query(conexao::Conectar(), "begin");
			
			if ($pfcid == PerfilComportamental::Gabinete) {
    			$carencia->vagaid = $vagaid;
    			$carencia->salvar();				
			}
			            	
        	$carencia->inserirHistorico($statusid, $parecer);
			        		
    	    pg_query(conexao::Conectar(), "commit");
		}
		catch (Exception $e){
            pg_query(conexao::Conectar(), "rollback");
            throw new Exception($e->getMessage());
		}
    }
    
    public static function reprovar(Carencia $carencia, $parecer)
    {
        self::isAuthorized('reprovar', $carencia, TRUE);
        
        if (empty($parecer)){
    	    throw new Exception("Parecer é obrigatório.");
    	}
    	
        global $pfcid;
    	
        switch ($pfcid) {
            case PerfilComportamental::Gabinete:
                $statusid = Status::Carencia_Reprovada_NucleoCentral;
                break;
            case PerfilComportamental::Orgao:
                $statusid = Status::Carencia_Reprovada_Orgao;
                break;
            default:
                throw new Exception('Solicitante Inválido.');
                break;
        }
    	
    	try {
			pg_query(conexao::Conectar(), "begin");
			
        	$carencia->ativa = FALSE;
        	$carencia->salvar();
        	
        	$carencia->inserirHistorico($statusid, $parecer);
			        		
    	    pg_query(conexao::Conectar(), "commit");
		}
		catch (Exception $e){
                pg_query(conexao::Conectar(), "rollback");
                throw new Exception($e->getMessage());
		}
    }
    
    public static function confirmar(Carencia $carencia, $parecer)
    {
        self::isAuthorized('confirmar', $carencia, TRUE);
        
        if (empty($parecer)){
    	    throw new Exception("Parecer é campo obrigatório.");
    	}
    	
        try {
			pg_query(conexao::Conectar(), "begin");
			
        	$carencia->ativa = FALSE;
        	$carencia->salvar();           	
        	
        	$carencia->inserirHistorico(Status::Carencia_Confirmada, $parecer);
        	
    	    $vaga = new Vaga($carencia->vagaid);
			$vaga->lotacaoid = $carencia->lotacaoid;
			$vaga->salvar();
			
			$selecao = new Selecao();
			$selecao->abrirProcesso($vaga->vagaid, FALSE, FALSE);
        	
        	pg_query(conexao::Conectar(), "commit");
		}
		catch (Exception $e){
            pg_query(conexao::Conectar(), "rollback");
            throw new Exception($e->getMessage());
		}
    }
    
    public static function cancelar(Carencia $carencia, $parecer)
    {
        self::isAuthorized('cancelar', $carencia, TRUE);
        
        if (empty($parecer)){
    	    throw new Exception("Parecer é campo obrigatório.");
    	}
    	
    	try {
			pg_query(conexao::Conectar(), "begin");
			
        	$carencia->ativa = FALSE;
        	$carencia->salvar();           	
        	
        	$carencia->inserirHistorico(Status::Carencia_Reprovada_Orgao, $parecer);
        	
        	pg_query(conexao::Conectar(), "commit");
		}
		catch (Exception $e){
            pg_query(conexao::Conectar(), "rollback");
            throw new Exception($e->getMessage());
		}
    }
    
    public static function isAuthorized($operacao, Carencia $carencia = NULL, $throwExceptions = FALSE)
    {
        $carencia = ($carencia) ? $carencia : new Carencia();
        $statusid = $carencia->getCarenciaHistoricoAtual()->statusid;
        
        global $pfcid, $usuario;
        
        if ($carencia->getTableKeyValue() AND $carencia->ativa == FALSE) {
            if ($throwExceptions) {
                throw new Exception('Não é possível realizar esta operação, pois esta carência está inativa.');
            }
            return FALSE;
        }
        
        if (!$usuario->isLotacaoPermitida($carencia->lotacaoid) AND 
            !$usuario->isVagaPermitida($carencia->vagaid)) {
            if ($throwExceptions) {
                $lotacao = new Lotacao($carencia->lotacaoid);
                throw new Exception('Não é possível realizar esta operação, pois você não tem acesso à lotação ' . $lotacao->fantasia . '.');
            }
            return FALSE;
        }
        
        switch ($operacao) {
            case 'solicitar':
                switch ($pfcid) {
                    case PerfilComportamental::Gabinete:
                    case PerfilComportamental::Orgao:
                    case PerfilComportamental::NucleoGestor:
                        if ($statusid == NULL) {
                            return TRUE;
                        }
                        break;                        
                }
            
            case 'reprovar':
            case 'aprovar':
                switch ($pfcid) {
                    case PerfilComportamental::Gabinete:
                        if ($statusid == Status::Carencia_Solicitada_Orgao
                            OR $statusid == Status::Carencia_Solicitada_NucleoCentral
                            OR $statusid == Status::Carencia_Aprovada_Orgao) {
                            return TRUE;
                        }
                        break;
                    case PerfilComportamental::Orgao:
                        if ($statusid == Status::Carencia_Solicitada_NucleoGestor
                            AND $pfcid == PerfilComportamental::Orgao) {
        				    return TRUE;
        				}
        				break;
                }
                break;

            case 'cancelar':
            case 'confirmar':
                if ($statusid == Status::Carencia_Aprovada_NucleoCentral
                    AND $pfcid == PerfilComportamental::Orgao) {
				    return TRUE;
				}
                break;
        }
        
        if ($throwExceptions) {
            throw new Exception(self::ERRO_AUTORIZACAO);
        }
        return FALSE;
    }
    
    public static function getAlertsStatus($pfcid)
    {
        switch ($pfcid) {
            case PerfilComportamental::Gabinete:
                return array(
                        Status::Carencia_Solicitada_NucleoCentral, 
                        Status::Carencia_Solicitada_Orgao,
                        Status::Carencia_Aprovada_Orgao
                );
                break;
                
            case PerfilComportamental::Orgao:
                return array(
                        Status::Carencia_Aprovada_NucleoCentral, 
                        Status::Carencia_Solicitada_NucleoGestor
                );
                break;
        }
    }
    
    /**
     * Verifica quais carências o usuário logado tem acesso sobre
     * @return string
     */
    public static function getFilterCarencia()
    {
        global $usuario;
        
        $where = '(
            (
                vagaid IS NULL AND
                lotacaoid IN (' . $usuario->getLotacoesFilterSQL() . ')
            ) OR  
            (
                vagaid IS NOT NULL AND
                vagaid IN (' . $usuario->getVagaFilterSQL() . ')
            )
        )';

        return $where;
    }
    
    public static function loadAlertsData($pfcid) 
    {
        $status = self::getAlertsStatus($pfcid);
        if ($status) {
            global $usuario;
            
            $status = TUtils::ArrayToSql($status);
            $view = new ViewCarenciaAcompanhamento();
            $where = 'statusid IN (' . $status . ')';
            
            $where .= ' AND ' . self::getFilterCarencia();
            
            $result = $view->listar(array(
            	'precondicao'=>$where, 
            	'orderBy'=>'dataregistro', 
            	'order'=>'desc'));
            
            if (pg_num_rows($result) > 0) {
                return pg_fetch_all($result);
            }
        }
    }
}